package com.godGuang.servser.impl;


import com.alibaba.fastjson.JSON;
import com.godGuang.domain.*;
import com.godGuang.mapper.ContentMapper;
import com.godGuang.servser.ContentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.godGuang.config.UniformConstant.PATIENTS;

/**
 * @author : 段敏强
 * @className : ContentServiceImpl
 * @description : 描述说明该类的功能
 * @createTime : 2024/01/08 14:15
 */

/**
 * 发布内容业务实现类
 */
@Service
public class ContentServiceImpl implements ContentService {


    /**
     * 内容Mapper
     */
    @Autowired
    private ContentMapper contentMapper;

    /**
     * redis
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 向内容列表中添加内容
     *
     * @param content 待添加的内容
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addContent(Content content) {
        // 根据科室类型ID获取部门类型信息
        Catalogue departmentType = contentMapper.contentById(content.getCatalogueId());
        // 设置内容创建时间
        content.setCreationTime(new Date());
        // 设置内容为未删除状态
        content.setDelete(0);

        // 对内容进行去敏感化处理
        char[] array = content.getContent().toCharArray();

        // 定义敏感词替换后的内容
        String hyposensitization = "";
        // 遍历字符数组，将敏感词替换为"***"
        for (char c : array) {
            hyposensitization += desensitizeText(String.valueOf(c));
        }

        // 设置内容为去敏感化后的内容
        content.setContent(hyposensitization);

        // 添加内容到列表中
        contentMapper.addContent(content);

        //更新Redis缓存
        redisTemplate.delete(PATIENTS);
        // 添加中间件信息，关联部门类型ID和内容ID
        contentMapper.addMiddle(departmentType.getCatalogueId(), content.getContentId());
    }

    /**
     * 根据科室类型ID获取内容列表
     *
     * @param catalogueId 科室类型ID
     * @return 内容列表
     */
    @Override
    public List<Content> createContentList(Integer catalogueId) {
        //返回内容列表
        return contentMapper.createContentList(catalogueId);
    }


    /**
     * 根据科室类型ID获取疾病列表
     *
     * @param catalogueId 科室类型ID
     * @return 疾病列表
     */
    @Override
    public List<Disease> diseaseList(String catalogueId) {

        //判断Redis中是否存在该科室类型ID的缓存
        Boolean aBoolean = redisTemplate.hasKey("diseaseList" + catalogueId);
        //判断Redis中是否存在该科室类型ID的缓存
        if (aBoolean) {
            //从Redis中获取内容列表
            List<String> range = redisTemplate.opsForList().range("diseaseList" + catalogueId, 0, -1);
            //将JSON字符串转换为对象
            ArrayList<Disease> diseases = new ArrayList<>();
            //将JSON字符串转换为对象
            for (String s : range) {
                //将JSON字符串转换为对象
                Disease disease = JSON.parseObject(s, Disease.class);
                //将对象添加到内容列表中
                diseases.add(disease);
            }
            //返回内容列表
            return diseases;
        }
        //从数据库中查询内容列表
        List<Disease> diseaseList = contentMapper.diseaseList(catalogueId);
        //将内容列表存入Redis中
        for (Disease disease : diseaseList) {
            //将内容列表存入Redis中
            redisTemplate.opsForList().rightPush("diseaseList" + catalogueId, JSON.toJSONString(disease));
        }
        //返回内容列表
        return diseaseList;
    }

    /**
     * 获取所有内容列表
     *
     * @return 内容列表
     */
    @Override
    public List<Content> list() {
        //判断Redis中是否存在该科室类型ID的缓存
        if (redisTemplate.hasKey(PATIENTS)) {
            //从Redis中获取内容列表
            List<String> range = redisTemplate.opsForList().range(PATIENTS, 0, -1);
            //将JSON字符串转换为对象
            ArrayList<Content> contents = new ArrayList<>();
            //将JSON字符串转换为对象
            for (String member : range) {
                //将JSON字符串转换为对象
                Content content = JSON.parseObject(member, Content.class);
                //将对象添加到内容列表中
                contents.add(content);
            }
            //返回内容列表
            return contents;
        }
        //从数据库中查询内容列表
        List<Content> list = contentMapper.list();
        //将内容列表存入Redis中
        for (Content content : list) {
            Integer review = contentMapper.reviewList(content.getContentId());
            Integer collect = contentMapper.collectList(content.getContentId());
            contentMapper.reviewAdd(content.getContentId(), review);
            contentMapper.collectAdd(content.getContentId(), collect);
            content.setReview(review);
            content.setCollect(collect);
            //将内容列表存入Redis中
            redisTemplate.opsForList().rightPush(PATIENTS, JSON.toJSONString(content));
        }
        //返回内容列表
        return list;
    }

    /**
     * 根据内容ID获取内容信息
     *
     * @param contentId 内容ID
     * @return 内容信息
     */
    @Override
    public Content contentById(String contentId) {
        //判断Redis中是否存在该科室类型ID的缓存
        return contentMapper.contentByIds(contentId);
    }

    /**
     * 内容加锁中间件数据操作
     *
     * @param contentEnshrineMiddle 内容加锁中间件对象
     * @return 返回内容加锁中间件对象
     */
    @Override
    public ContentEnshrineMiddle contentEnshrineMiddleData(ContentEnshrineMiddle contentEnshrineMiddle) {
        //添加内容加锁中间件数据
        return contentMapper.contentEnshrineMiddleData(contentEnshrineMiddle);
    }

    /**
     * 在内容中间添加封装对象
     *
     * @param enshrine 封装对象
     */
    @Override
    public void contentEnshrineMiddleAdd(Enshrine enshrine) {

        //获取中间件数据
        ContentEnshrineMiddle contentEnshrineMiddle = contentMapper.contentEnshrineMiddleData(
                new ContentEnshrineMiddle(enshrine.getContentId(), enshrine.getUserId()));

        if (null == contentEnshrineMiddle) {
            //添加收藏表数据
            contentMapper.enshrineAdd(enshrine);
            //添加建议收藏数量中间表数据
            contentMapper.contentEnshrineMiddleAdd(enshrine.getContentId(), enshrine.getUserId());
            //删除内容列表缓存
            redisTemplate.delete(PATIENTS);
            redisTemplate.delete("userId" + enshrine.getUserId());
        } else {
            contentMapper.contentEnshrineMiddleDelete(enshrine.getContentId(), enshrine.getUserId());
            //删除内容列表缓存
            redisTemplate.delete(PATIENTS);
            redisTemplate.delete("userId" + enshrine.getUserId());
        }

    }

    /**
     * 获取用户收藏的内容列表
     *
     * @param userId 用户ID
     * @return 用户收藏的内容列表
     */
    @Override
    public List<Content> myCollectionList(String userId) {
        //判断Redis中是否存在该用户ID的缓存
        if (redisTemplate.hasKey("userId" + userId)) {
            //从Redis中获取内容列表
            List<String> range = redisTemplate.opsForList().range("userId" + userId, 0, -1);
            //将JSON字符串转换为对象
            ArrayList<Content> contents = new ArrayList<>();
            //将JSON字符串转换为对象
            for (String column : range) {
                //将JSON字符串转换为对象
                Content content = JSON.parseObject(column, Content.class);
                //将对象添加到内容列表中
                contents.add(content);
            }
            //返回内容列表
            return contents;
        }
        //从数据库中查询内容列表
        List<Content> contents = contentMapper.myCollectionList(userId);
        //将内容列表存入Redis中
        for (Content content : contents) {
            //将内容列表存入Redis中
            redisTemplate.opsForList().rightPush("userId" + userId, JSON.toJSONString(content));
        }
        //返回内容列表
        return contents;
    }

    /**
     * 获取指定用户的个人发布列表
     *
     * @param userId 用户ID
     * @return 返回指定用户的个人发布列表
     */
    @Override
    public List<Content> personalPublishingList(String userId) {
        //判断Redis中是否存在该用户ID的缓存
        return contentMapper.personalPublishingList(userId);
    }


    /**
     * 对原始文本进行去敏感化处理，将敏感词替换为"***"。
     *
     * @param originalText 原始文本
     * @return 去敏感化后的文本
     */
    public static String desensitizeText(String originalText) {
        // 敏感词数组
        String[] sensitiveKeywords = {"最", "黄", "赌", "毒", "逼", "嫖", "鸡", "精", "草", "艹"};
        // 定义敏感词替换后的文本
        String desensitizedText = originalText;
        for (String keyword : sensitiveKeywords) {
            // 使用正则表达式替换敏感词
            Pattern pattern = Pattern.compile(keyword, Pattern.CASE_INSENSITIVE);
            // 忽略大小写的写法：Pattern.CASE_INSENSITIVE
            Matcher matcher = pattern.matcher(desensitizedText);
            // 使用正则表达式替换敏感词
            desensitizedText = matcher.replaceAll("*"); // 将敏感词替换为***
        }
        // 返回去敏感化后的文本
        return desensitizedText;
    }


}
